package com.quectel.mobile.controller.forum;

import cn.hutool.core.lang.func.LambdaUtil;
import com.quectel.business.common.file.FileBusiness;
import com.quectel.business.common.forum.ForumMuteBusiness;
import com.quectel.business.common.forum.ForumTopicBusiness;
import com.quectel.business.common.forum.vo.ForumMuteVo;
import com.quectel.business.contentaudit.ValidatorChain;
import com.quectel.business.contentaudit.ValidatorContext;
import com.quectel.constant.core.forum.ForumConstants;
import com.quectel.constant.global.SystemConstants;
import com.quectel.core.module.forum.dto.ForumTopicDto;
import com.quectel.core.module.forum.dto.mongo.ForumPostDto;
import com.quectel.core.module.forum.service.ForumTopicService;
import com.quectel.core.module.forum.service.mongo.ForumLikeService;
import com.quectel.core.module.forum.service.mongo.ForumPostService;
import com.quectel.core.module.household.dto.HouseholdDto;
import com.quectel.core.module.village.dto.VillageDto;
import com.quectel.core.module.village.service.VillageService;
import com.quectel.mobile.controller.BaseController;
import com.quectel.mobile.util.SessionHolder;
import com.quectel.mobile.vo.forum.ForumCommentReq;
import com.quectel.mobile.vo.forum.ForumLikeReq;
import com.quectel.util.common.Page;
import com.quectel.util.common.Request;
import com.quectel.util.common.Response;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zhangheng
 * @email nolan.zhang@quectel.com
 * @date 2023/5/15 9:24
 * @description 发帖相关
 */
@RestController
@RequestMapping("forumPost")
@Tag(name = "ForumPostController", description = "发帖相关api")
public class ForumPostController extends BaseController {

    @DubboReference
    private ForumPostService forumPostService;
    @DubboReference
    private ForumTopicService forumTopicService;
    @DubboReference
    private ForumLikeService forumLikeService;
    @DubboReference
    private VillageService villageService;

    @Autowired
    private ForumMuteBusiness forumMuteBusiness;
    @Autowired
    private FileBusiness fileBusiness;
    @Autowired
    private ValidatorChain validatorChain;
    @Autowired
    private ForumTopicBusiness forumTopicBusiness;


    /**
     * 帖子列表
     *
     * @param
     * @return
     */

    @GetMapping("list")
    @Operation(summary = "帖子列表查询")
    public Response<Page<ForumPostDto>> list(
            @Parameter(description = "从1开始的页码数") @RequestParam Integer pageNo,
            @Parameter(description = "每页多少条") @RequestParam Integer pageSize,
            @Parameter(description = "查询范围1小区2城市3全国,当范围是1时传villageId,2时传cityCode")
            @RequestParam Byte queryRange,
            @Parameter(description = "类别,默认没有类别") @RequestParam(required = false) Byte type,
            @Parameter(description = "话题Id") @RequestParam(required = false) Long topicId,
            @Parameter(description = "查询content") @RequestParam(required = false) String queryContent
    ) {
        Request request = Request.configParams(Request.parseParams(httpServletRequest));

        HouseholdDto currentHousehold = null;
        if (SessionHolder.getLoginMobileUserSession() != null) {
            request.put(LambdaUtil.getFieldName(ForumPostDto::getTenantId), SessionHolder.getLoginMobileUserSession().getTenantId());
            currentHousehold = SessionHolder.getLoginMobileUserSession().getCurrentHousehold();
        } else {
            //如果为空则拿不到tenantId 则不查询
            return Response.<Page<ForumPostDto>>ok().wrap(Page.empty(request.getPageNo(), request.getPageSize()));
        }
        //如果没有认证 则仅看开放帖子
        //如果是城市范围和租户范围 仅看开放帖子
        if (currentHousehold == null || ForumConstants.ForumRange.CITY.getRange().equals(queryRange)
                || ForumConstants.ForumRange.ALL.getRange().equals(queryRange)) {
            request.put(LambdaUtil.getFieldName(ForumPostDto::getVisibleFlag), SystemConstants.YES);
        }
        //如果是小区帖子,查看本小区的帖子
        if (ForumConstants.ForumRange.VILLAGE.getRange().equals(queryRange)) {
            request.put(LambdaUtil.getFieldName(ForumPostDto::getVillageId), SessionHolder.getLoginMobileUserSession().getCurrentVillageId());
        }

        if (ForumConstants.ForumRange.CITY.getRange().equals(queryRange)) {
            VillageDto villageDto = villageService.selectCacheById(SessionHolder.getLoginMobileUserSession().getCurrentVillageId());
            if (villageDto == null) {
                return Response.error("未查询到小区信息");
            }
            request.put(LambdaUtil.getFieldName(ForumPostDto::getCityCode), villageDto.getCityCode());
        }

        if (type != null) {
            request.put(LambdaUtil.getFieldName(ForumPostDto::getType), type);
        }

        if (topicId != null) {
            request.put(LambdaUtil.getFieldName(ForumPostDto::getTopics), new Long[]{topicId});
        }

        if (StringUtils.isNotBlank(queryContent)) {
            request.put(LambdaUtil.getFieldName(ForumPostDto::getContent), queryContent);
        }

        if (SessionHolder.getLoginMobileUserSession() != null && SessionHolder.getLoginMobileUserSession().getMobileUser() != null) {
            //当前用户 用来标记帖子是否是自己的
            request.put(ForumConstants.CURRENT_USER, SessionHolder.getLoginMobileUserSession().getMobileUser().getId());
        }

        //未删除的帖子
        request.put(LambdaUtil.getFieldName(ForumPostDto::getDeletedFlag), SystemConstants.NO);

        List<ForumPostDto> forumPostDtos = forumPostService.queryList(request.getParams());

        Page<ForumPostDto> page = new Page<>(request.getPageNo(), request.getPageSize(), 0, forumPostDtos);
        return Response.<Page<ForumPostDto>>ok().wrap(page);
    }

    /**
     * 发帖
     *
     * @param content
     * @return
     */
    @PostMapping(value = "post", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
    @Operation(summary = "发帖")
    public Response<Object> post(
            @Parameter(description = "发帖内容") @RequestParam(value = "content") String content,
            @Parameter(description = "所属类别") @RequestParam(value = "type") Byte type,
            @Parameter(description = "其他小区是否可见,1可见0不可见") @RequestParam(value = "visibleFlag") Byte visibleFlag,
            @Parameter(description = "图片列表") @RequestParam(value = "images", required = false) MultipartFile[] images,
            @Parameter(description = "话题列表") @RequestParam(value = "topics", required = false) List<Long> topics

    ) {
        HouseholdDto currentHousehold = SessionHolder.getLoginMobileUserSession().getCurrentHousehold();
        if (currentHousehold == null) {
            return Response.error("请先认证住户");
        }
        //黑名单查询
        ForumMuteVo muteStatus = forumMuteBusiness.getMuteStatus(SessionHolder.getLoginMobileUserSession().getTenantId(), SessionHolder.getLoginMobileUserSession().getMobileUser().getId());
        if (muteStatus != null && SystemConstants.NO.equals(muteStatus.getStatus())) {
            return Response.error(muteStatus.getRecordText());
        }

        VillageDto villageDto = villageService.selectCacheById(currentHousehold.getVillageId());
        if (villageDto == null) {
            return Response.error("获取小区信息失败，请联系管理员");
        }

        if (StringUtils.isBlank(content)) {
            return Response.error("内容不能为空");
        }

        if (CollectionUtils.isNotEmpty(topics)) {
            List<Long> distinctTopics = topics.stream().distinct().collect(Collectors.toList());
            //话题是否合法
            Map<String, Object> topicOptions = new HashMap<>(2);
            topicOptions.put(LambdaUtil.getFieldName(ForumTopicDto::getStatus), SystemConstants.COMMON);

            List<ForumTopicDto> topicsByVillageId = forumTopicBusiness.getVillageTopic(Collections.singletonList(villageDto.getId()), topicOptions);
            Set<Long> villageTopics = topicsByVillageId.stream().map(ForumTopicDto::getId).collect(Collectors.toSet());

            if (!villageTopics.containsAll(distinctTopics)) {
                return Response.error("话题参数非法");
            }
        }

        //处理图片,将文件写入临时文件夹
        Response<List<String>> imgFilePathsResponse = fileBusiness.handleFileToTempPaths(images, ForumConstants.IMG_ACCEPT_TYPE);
        if (!imgFilePathsResponse.isSuccess()) {
            return Response.error(imgFilePathsResponse.getMessage());
        }
        //校验发帖内容
        ValidatorContext validatorContext = new ValidatorContext();
        validatorContext.setTenantId(SessionHolder.getLoginMobileUserSession().getTenantId());
        validatorContext.setVillageId(SessionHolder.getLoginMobileUserSession().getCurrentVillageId());
        validatorContext.setText(content);
        validatorContext.setFilePaths(imgFilePathsResponse.getData());

        Response validateResult = validatorChain.validate(validatorContext);
        if (!validateResult.isSuccess()) {
            return Response.<Object>ok().wrap(validateResult);
        }

        Response<List<String>> imageUrlsResponse = fileBusiness.batchUploadFile(imgFilePathsResponse.getData());
        if (!imageUrlsResponse.isSuccess()) {
            return Response.error(imageUrlsResponse.getMessage());
        }

        //保存发帖内容
        ForumPostDto dto = new ForumPostDto();
        dto.setTenantId(SessionHolder.getLoginMobileUserSession().getTenantId());
        dto.setCityCode(villageDto.getCityCode());
        dto.setAuthorId(SessionHolder.getLoginMobileUserSession().getMobileUser().getId());
        dto.setType(type);
        dto.setTopics(topics);
        dto.setContent(content);
        dto.setImageUrls(imageUrlsResponse.getData());
        dto.setVisibleFlag(visibleFlag);
        dto.setPublishTime(new Date());
        dto.setVillageId(villageDto.getId());
        dto.setTopFlag(SystemConstants.NO);

        //保存
        Long save = forumPostService.post(dto);
        return Response.<Object>ok().wrap(save);
    }


    /**
     * 点赞 不需要认证 需要登录
     *
     * @param forumLikeReq
     * @return
     */
    @PostMapping(value = "like")
    @Operation(summary = "点赞,取消点赞操作")
    public Response<Object> like(
            @RequestBody ForumLikeReq forumLikeReq
    ) {
        if (SessionHolder.getLoginMobileUserSession().getMobileUser() == null) {
            return Response.error("请登录后操作");
        }

        if (!forumLikeReq.getStatus().equals(SystemConstants.YES) && !forumLikeReq.getStatus().equals(SystemConstants.NO)) {
            return Response.error(SystemConstants.ILLEGAL_MSG);
        }

        //查询帖子
        ForumPostDto dto = forumPostService.selectById(forumLikeReq.getPostId());

        if (dto == null || SystemConstants.YES.equals(dto.getDeletedFlag())) {
            return Response.error("您要点赞的帖子已被删除");
        }

        //执行
        forumPostService.like(dto.getId(), SessionHolder.getLoginMobileUserSession().getMobileUser().getId(), forumLikeReq.getStatus());
        return Response.<Object>ok().wrap(null);
    }

    /**
     * 评论需要认证
     *
     * @param forumCommentReq
     * @return
     */
    @PostMapping(value = "comment")
    @Operation(summary = "评论")
    public Response<Object> comment(
            @RequestBody ForumCommentReq forumCommentReq
    ) {
        HouseholdDto currentHousehold = SessionHolder.getLoginMobileUserSession().getCurrentHousehold();
        if (currentHousehold == null) {
            return Response.error("请先进行身份认证");
        }
        //黑名单查询
        ForumMuteVo muteStatus = forumMuteBusiness.getMuteStatus(SessionHolder.getLoginMobileUserSession().getTenantId(), SessionHolder.getLoginMobileUserSession().getMobileUser().getId());
        if (muteStatus != null && SystemConstants.NO.equals(muteStatus.getStatus())) {
            return Response.error(muteStatus.getRecordText());
        }

        //查询帖子
        ForumPostDto dto = forumPostService.selectById(forumCommentReq.getPostId());

        if (dto == null || SystemConstants.YES.equals(dto.getDeletedFlag())) {
            return Response.error("您要评论的帖子已被删除");
        }

        //校验发帖内容
        ValidatorContext validatorContext = new ValidatorContext();
        validatorContext.setTenantId(SessionHolder.getLoginMobileUserSession().getTenantId());
        validatorContext.setVillageId(SessionHolder.getLoginMobileUserSession().getCurrentVillageId());
        validatorContext.setText(forumCommentReq.getComment());

        Response validateResult = validatorChain.validate(validatorContext);
        if (!validateResult.isSuccess()) {
            return Response.<Object>ok().wrap(validateResult);
        }

        //执行
        forumPostService.comment(dto.getId(), SessionHolder.getLoginMobileUserSession().getMobileUser().getId(), currentHousehold.getId(), forumCommentReq.getComment());
        return Response.<Object>ok().wrap(null);
    }

    /**
     * 分享 不需要认证
     *
     * @param postId
     * @return
     */
    @PostMapping(value = "share")
    @Operation(summary = "分享")
    public Response<Object> share(
            @RequestBody Long postId
    ) {
        if (SessionHolder.getLoginMobileUserSession().getMobileUser() == null) {
            return Response.error("请登录后操作");
        }
        //查询帖子
        ForumPostDto dto = forumPostService.selectById(postId);

        if (dto == null || SystemConstants.YES.equals(dto.getDeletedFlag())) {
            return Response.error("您要分享的帖子已被删除");
        }

        //执行
        forumPostService.share(dto.getId(), SessionHolder.getLoginMobileUserSession().getMobileUser().getId());
        return Response.<Object>ok().wrap(null);
    }

    //查看详情

    /**
     * 信息
     */
    @GetMapping("info/{id}")
    @Operation(summary = "通过Id查询帖子详情")
    public Response<ForumPostDto> info(@PathVariable("id") Long id) {

        //查询帖子
        ForumPostDto dto = forumPostService.selectById(id);

        if (dto == null || SystemConstants.YES.equals(dto.getDeletedFlag())) {
            return Response.error("您要查询的帖子已被删除");
        }

        if (SessionHolder.getLoginMobileUserSession() != null && SessionHolder.getLoginMobileUserSession().getMobileUser() != null) {
            //是否是作者
            Long currentUser = SessionHolder.getLoginMobileUserSession().getMobileUser().getId();
            dto.setAuthorFlag(forumPostService.isAuthor(dto.getAuthorId(), currentUser));
            //是否点过赞
            dto.setLikeFlag(forumPostService.ifLike(dto.getId(), currentUser));
        }

        return Response.<ForumPostDto>ok().wrap(dto);
    }


    /**
     * 修改
     */
    @PostMapping(value = "update", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
    @Operation(summary = "更新帖子,更新内容,图片和是否可见")
    public Response<Object> update(
            @Parameter(description = "帖子Id") @RequestParam(value = "postId") Long postId,
            @Parameter(description = "发帖内容") @RequestParam(value = "content") String content,
            @Parameter(description = "其他小区是否可见,1可见0不可见") @RequestParam(value = "visibleFlag") Byte visibleFlag,
            @Parameter(description = "图片列表") @RequestParam(value = "images", required = false) MultipartFile[] images,
            @Parameter(description = "上传过的图片url") @RequestParam(value = "imgUrls", required = false) List<String> imgUrls
    ) {

        HouseholdDto currentHousehold = SessionHolder.getLoginMobileUserSession().getCurrentHousehold();
        if (currentHousehold == null) {
            return Response.error("请先认证住户");
        }

        //黑名单查询
        ForumMuteVo muteStatus = forumMuteBusiness.getMuteStatus(SessionHolder.getLoginMobileUserSession().getTenantId(), SessionHolder.getLoginMobileUserSession().getMobileUser().getId());
        if (muteStatus != null && SystemConstants.NO.equals(muteStatus.getStatus())) {
            return Response.error(muteStatus.getRecordText());
        }

        //是否有操作权限
        ForumPostDto dto = forumPostService.selectById(postId);
        if (dto == null || SystemConstants.YES.equals(dto.getDeletedFlag())) {
            return Response.error("帖子已经被删除");
        }
        if (!dto.getAuthorId().equals(SessionHolder.getLoginMobileUserSession().getMobileUser().getId())) {
            return Response.error(SystemConstants.ILLEGAL_MSG);
        }

        if (StringUtils.isBlank(content)) {
            return Response.error("内容不能为空");
        }
        //如果原来没有图片上传了图片链接 则不通过
        if (CollectionUtils.isEmpty(dto.getImageUrls()) && CollectionUtils.isNotEmpty(imgUrls)) {
            return Response.error(SystemConstants.ILLEGAL_MSG);
        }
        //如果新上传的图片链接不在原来的图片列表中 则不通过
        if (CollectionUtils.isNotEmpty(dto.getImageUrls()) && !new HashSet<>(dto.getImageUrls()).containsAll(imgUrls)) {
            return Response.error(SystemConstants.ILLEGAL_MSG);
        }

        //处理图片,将文件写入临时文件夹
        Response<List<String>> imgFilePathsResponse = fileBusiness.handleFileToTempPaths(images, ForumConstants.IMG_ACCEPT_TYPE);
        if (!imgFilePathsResponse.isSuccess()) {
            return Response.error(imgFilePathsResponse.getMessage());
        }
        //校验发帖内容
        ValidatorContext validatorContext = new ValidatorContext();
        validatorContext.setTenantId(SessionHolder.getLoginMobileUserSession().getTenantId());
        validatorContext.setVillageId(SessionHolder.getLoginMobileUserSession().getCurrentVillageId());
        validatorContext.setText(content);
        validatorContext.setFilePaths(imgFilePathsResponse.getData());

        Response validateResult = validatorChain.validate(validatorContext);
        if (!validateResult.isSuccess()) {
            return Response.<Object>ok().wrap(validateResult);
        }

        Response<List<String>> imageUrlsResponse = fileBusiness.batchUploadFile(imgFilePathsResponse.getData());
        if (!imageUrlsResponse.isSuccess()) {
            return Response.error(imageUrlsResponse.getMessage());
        }

        if (imgUrls == null) {
            imgUrls = new ArrayList<>();
        }

        if (imageUrlsResponse.getData() != null) {
            imgUrls.addAll(imageUrlsResponse.getData());
        }

        //保存发帖内容
        dto.setContent(content);
        dto.setImageUrls(imgUrls);
        dto.setVisibleFlag(visibleFlag);
        dto.setEditTime(new Date());
        forumPostService.updateById(dto);

        return Response.<Object>ok().wrap(dto.getId());
    }

    /**
     * 删除
     */
    @PostMapping("delete")
    @Operation(summary = "根据Id删除帖子")
    public Response<Object> delete(@RequestBody Long id) {
        HouseholdDto currentHousehold = SessionHolder.getLoginMobileUserSession().getCurrentHousehold();
        if (currentHousehold == null) {
            return Response.error("请先认证住户");
        }

        //是否有操作权限
        ForumPostDto dto = forumPostService.selectById(id);
        if (dto == null || SystemConstants.YES.equals(dto.getDeletedFlag())) {
            return Response.error("帖子已经被删除");
        }
        if (!dto.getAuthorId().equals(SessionHolder.getLoginMobileUserSession().getMobileUser().getId())) {
            return Response.error(SystemConstants.ILLEGAL_MSG);
        }
        //标记删除
        forumPostService.logicDeleteById(id);

        return Response.ok();
    }
}
